﻿#include "GLLInc.h"
#include "GLLMacro.h"
#include "GLLObjMgr.h"
//特定类：
#include "GLLCamera.h"
#include "GLLObjSpcl.h"

namespace GLL
{
	void ObjectManager::_delete_Object(Object* p)
	{
		//GLL_LOG("del_obj, %p\n", p);
		//删除指针
		GLL_DEL(p);
	}

	Object* ObjectManager::_new_Object( Object::ID i )
	{
		Object* obj = 0;
		switch(i.type)
		{
		case Object::OT_Light:

			break;
		case Object::OT_Camera:
			obj = GLL_NEW ObjectCamera();
			break;
		case Object::OT_Particle:

			break;
		case Object::OT_Mesh:
			obj = GLL_NEW ObjectMesh();
			break;
		case Object::OT_Helper: 

			break;
		}
		//GLL_LOG("new_obj, %p\n", obj);
		return obj;
	}

#define LOCK_OBJECTS	LOCK_MUTEX(_objMutex)

	ObjSrdPtr ObjectManager::_CreateObject( Object::ID oid )
	{
		if(oid.index == nullindex)
		{
			GLL_Throw("index is 0. ObjectManager::CreateObject");
		}

		if(_HasObject(oid))
		{
			StringStream strm;
			strm << "create object already has:" << Object::ID2String(oid);
			GLL_Throw(strm);
		}

		Object* pObj = _new_Object(oid);
		if(!pObj){
			StringStream strm;
			strm << "new Object Failed, type:" << Object::ID2String(oid);
			GLL_Throw(strm);
		}

		pObj->_id = oid;
		pObj->_mgr = this;
		ObjSrdPtr srdPtr(pObj);
		AdoptObject(srdPtr);
		return srdPtr;
	}


	bool ObjectManager::_HasObject( Object::ID oid)
	{
		LOCK_OBJECTS;
		ObjectMap::iterator iter = _objects.find(oid);
		return (iter != _objects.end());
	}

	ObjSrdPtr ObjectManager::_FindObject( Object::ID oid)
	{
		LOCK_OBJECTS;
		ObjectMap::iterator iter = _objects.find(oid);
		if(iter == _objects.end())
		{
			SS ss; ss << "no such Object " << Object::ID2String(oid);
			GLL_Throw(ss);
		}
		return iter->second;
	}

	void ObjectManager::AdoptObject( ObjSrdPtr pSrdObj )
	{
		LOCK_OBJECTS;
		_objects[pSrdObj->GetID()] = pSrdObj;
	}

	ObjSrdPtr ObjectManager::_DestroyObject( Object::ID oid)
	{
		LOCK_OBJECTS;
		ObjectMap::iterator iter = _objects.find(oid);

		if(iter == _objects.end())
		{
			SS ss; ss << "获取一个不存在的物体:"<<Object::ID2String(oid);
			GLL_Throw(ss);
		}

		ObjSrdPtr ptr = iter->second;
		//解除引用
		_objects.erase(iter);
		return ptr;
	}

	void ObjectManager::_GetTempObjectVec(ObjectVec& ObjVec)
	{
		//保留现场，
		LOCK_OBJECTS;
		ObjVec.reserve(_objects.size());
		ObjectMap::iterator iter = _objects.begin();
		for(; iter != _objects.end(); ++iter)
		{
			ObjSrdPtr ptr = iter->second;
			ObjVec.push_back(ptr);
		}
	}


	void ObjectManager::Update_AllObjects( TimeMS ms)
	{
		ObjectVec objVec;
		_GetTempObjectVec(objVec);

		BOOST_FOREACH(ObjSrdPtr ptr, objVec)
		{
			if(!ptr){
				GLL_BreakPoint;
			}else{
				ptr->Update(ms);
			}
		}
	}
};//GLL

//-----------------------------------------------------------------------------
namespace boost
{
	void checked_delete(GLL::Object* x)
	{
		if(!x) return;
		assert(x->_Mgr);
		x->GetMgr()->_delete_Object(x);
	}
}
